#include "Catapult.h"
#include "File.h"
#include "Factory.h"
#include "ReportError.h"
#include "MeshManager.h"
#include "PlayState.h"
#include "Timer.h"
#include "RadDegConvert.h"
#include "ToPlayStateFunctor.h"
#include <gl\glut.h>

Catapult::Catapult()
{
	//Two parts
	//Arm and base
	//Arm needs to rotate about its hinge
	//Arm needs to collide with projectile
	//m_mat.SetIdentity();
	m_isAiming = true;
	m_isTurningRight = false;
	m_isTurningLeft = false;
	m_isFiring = false;
	m_isReadyFire = false;
	m_hasFired = false;
	m_isReseting = false;
	m_isWaiting = false;
	m_firingSpeed = 5;
	m_mat.SetIdentity();
	m_yRotation = 0;
	m_armRotation = 0;
	m_pos = Vec3f(0, 8 , 0);

	TheEventPoller::Instance()->AddHandler(this);
}

void Catapult::Draw()
{
	
	glPushMatrix();
		glMatrixMode (GL_MODELVIEW);

		//Draw catapult base
		glPushMatrix();
		
			glRotatef(m_yRotation, 0, 1, 0);
			TheTextureManager::Instance()->DrawTexture(m_texPath);
			TheMeshManager::Instance()->DrawMesh(m_baseMeshPath);
		
		glPopMatrix();

		//Rotate the whole catapult around its Y axis
		/*btTransform btTrans;
		btQuaternion quat;
		quat.setEuler( m_yRotation, m_armRotation, 0 );
		btTrans.setOrigin(btVector3(m_pos.X, m_pos.Y, m_pos.Z));
		mp_rigidBody->setWorldTransform(btTrans);*/
		
		//btTrans.setRotation(quat);

		btTransform btTrans;
		btTrans = mp_rigidBody->getWorldTransform();
		btTrans.getOpenGLMatrix(m_mat.m_matrix);
		m_mat.MultiOpenGL();
		
		TheMeshManager::Instance()->DrawMesh(m_armMeshPath);

	glPopMatrix();

}

void Catapult::Update()
{
	mp_rigidBody->activate(true);

	float dt = TheTimer::Instance()->GetDT();

	btTransform btTrans;
	btQuaternion quat;
	quat.setEuler( DegToRad(m_yRotation), m_armRotation, 0 );
	btTrans.setOrigin(btVector3(m_pos.X, m_pos.Y, m_pos.Z));
	btTrans.setRotation(quat);
	mp_rigidBody->setWorldTransform(btTrans);

	if(m_isAiming)
	{
		m_armRotation = 0;
		if(m_isTurningLeft)
		{
			m_yRotation += 8.f * dt;
		}
		else if(m_isTurningRight)
		{
			m_yRotation -= 8.f * dt;
		}
	}
	if(m_hasFired)
	{
		m_isWaiting = true;
		//m_isAiming = false;
		m_armRotation -= m_firingSpeed * dt;
		if(m_armRotation < -1.4f)
		{
			m_hasFired = false;
			m_isReseting = true;
			
		}
	}
	if(m_isReseting || m_isWaiting)
	{

		m_armRotation += 1 * dt;
		if(m_armRotation > -0.05f && m_armRotation < 0.05f)
		{
			m_isReseting = false;
		}
	}
	
}


void Catapult::OnKeyboardEvent(const SDL_KeyboardEvent& k)
 {
	if(k.keysym.sym == SDLK_SPACE && k.state == SDL_PRESSED)
	{
		if(m_isAiming)
		{
			m_isFiring = true;
			m_isAiming = false;
		}
	}
	if(m_isFiring)
	{
		if(k.keysym.sym == SDLK_SPACE && k.state == SDL_RELEASED)
		{
			m_isReadyFire = true;
		}
	}
	if(k.keysym.sym == SDLK_d && k.state == SDL_PRESSED)
	{
		//m_yRotation -= 0.25f;
		m_isTurningRight = true;
	}
	else if(k.keysym.sym == SDLK_d && k.state == SDL_RELEASED)
	{
		//m_yRotation -= 0.25f;
		m_isTurningRight = false;
	}
	if(k.keysym.sym == SDLK_a && k.state == SDL_PRESSED)
	{
		//m_yRotation += 0.25f;
		m_isTurningLeft = true;
	}
	else if(k.keysym.sym == SDLK_a && k.state == SDL_RELEASED)
	{
		//m_yRotation -= 0.25f;
		m_isTurningLeft = false;
	}
}

void Catapult::MakeAiming()
{
	m_isAiming = true;
	m_isWaiting = false;
	m_isFiring = false;
	m_hasFired = false;
	m_isReseting = false;
}

void Catapult::SetFiringSpeed(float fire)
{
	m_firingSpeed = fire;
}

void Catapult::Fire()
{
	if(m_isAiming)
	{
		m_isFiring = true;
		m_isAiming = false;
	}
}

bool Catapult::GetIsReadyFire()
{
	return m_isReadyFire;
}
void Catapult::TurnLeft()
{
	if(m_isAiming)
	{
		m_isTurningLeft = true;
	}
}
void Catapult::TurnRight()
{
	m_isTurningRight = true;
}



bool Catapult::Load(File* const f)
{

	if(!f->GetString(&m_armMeshPath))
	{
		ReportError("Catapult arm mesh path not found");
	}
	if(!f->GetString(&m_baseMeshPath))
	{
		ReportError("Catapult base mesh path not found");
	}

	ThePlayState::Instance()->SetCatapultAddress(this);

	MakeStaticCollisionShapeFromMesh(TheMeshManager::Instance()->GetMesh(m_armMeshPath), 0, COL_CATAPULT, catapultCollidesWith);	
	
	btTransform bt;
	bt.setOrigin(btVector3( 0, 0, -50));
	mp_rigidBody->setCenterOfMassTransform(bt);
	
	if(!f->GetString(&m_texPath))
	{
		ReportError("Catapult texture not found");
	}

	return true;
}

float Catapult::GetYRotation()
{
	return m_yRotation;
}

void Catapult::HasFired()
{
	m_isFiring = false;
	m_isReadyFire = false;
	m_hasFired = true;
}

bool Catapult::GetHasFired()
{
	return m_hasFired;
}

bool Catapult::GetIsWaiting()
{
	return m_isWaiting;
}

bool Catapult::GetIsAiming()
{

	return m_isAiming;
}

bool Catapult::GetIsFiring()
{
	return m_isFiring;
}

const char* Catapult::GetTypeName()
{
	return "Catapult";
}

Catapult::~Catapult()
{
	TheEventPoller::Instance()->RemoveHandler(this);
}

GameObject* CreateCatapult()
{
	return new Catapult;
}

static bool cata = TheGameObjectFactory::Instance()->AddToMap("Catapult", CreateCatapult);